package com.szwistar.common.os;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.nio.charset.Charset;

/**
 * 文件读取工具类
 */
public class FileUtils {
	/**
	 * 读取输入流到 byte[] 数组，并关闭输入流
	 */
	public static byte[] readStreamAsBytes(InputStream ins) throws Exception {
		if(ins == null) { return null; }
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try {
			short bufSize = 1024;
			byte[] buffer = new byte[bufSize];
			int len;
			while (-1 != (len = ins.read(buffer, 0, bufSize))) {
				bos.write(buffer, 0, len);
			}
			return bos.toByteArray();
		} finally {
			close(ins);
			close(bos);
		}
	}

	/**
	 * 读取流内容，作为字符串(UTF8编码)返回，并关闭输入流
	 */
	public static String readStreamAsString(InputStream ins) throws Exception {
		if(ins == null) { return null; }
		try {
			StringBuilder sb = new StringBuilder();
			byte[] bbuf = new byte[1024]; 			// 创建一个Buffer
			int hasRead = 0; 						// 用于保存实际读取的字节数
			Charset charsetUTF8 = Charset.forName("UTF-8");

			while ((hasRead = ins.read(bbuf)) > 0) {
				sb.append(new String(bbuf, 0, hasRead, charsetUTF8));
			}
			return sb.toString();
		} finally {
			close(ins);
		}
	}

	/**
	 * 读取文件到 byte[] 数组
	 */
	public static byte[] readFileAsBytes(File file) throws Exception {
		return readStreamAsBytes(new FileInputStream(file));
	}

	/**
	 * 读取文件内容，作为字符串(UTF8编码)返回
	 */
	public static String readFileAsString(String filePath) throws Exception {
		return readFileAsString(new File(filePath));
	}

	/**
	 * 读取文件内容，作为字符串(UTF8编码)返回
	 */
	public static String readFileAsString(File file) throws Exception {
		if (file.length() > 1024 * 1024 * 1024) {
			throw new Exception("File is too large");
		}

		return readStreamAsString(new FileInputStream(file));
	}

	/**
	 * 读取clazz 所在 jar 包中的文件数据
	 */
	public static String readResourceAsString(Class<?> clazz, String path) throws Exception {
		return (clazz != null) ?
			readStreamAsString(clazz.getClassLoader().getResourceAsStream(path)) :
			readStreamAsString(ClassLoader.getSystemResourceAsStream(path));
	}

	/**
	 * 读取clazz 所在 jar 包中的文件数据
	 */
	public static byte[] readResourceAsBytes(Class<?> clazz, String path) throws Exception {
		return (clazz != null) ?
			readStreamAsBytes(clazz.getClassLoader().getResourceAsStream(path)) :
			readStreamAsBytes(ClassLoader.getSystemResourceAsStream(path));
	}

	/**
	 * 保存字符串到文件
	 */
	public static void writeFile(File file, String text) throws Exception {
		FileWriter fileWriter = null;
		try {
			fileWriter = new FileWriter(file);
			fileWriter.write(text);
		} finally {
	        close(fileWriter);
		}
	}

	/**
	 *将字节数组保存到文件
	 */
	public static void writeFile(File file, byte[] bytes, int offset, int len) throws Exception {
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(file);
	        out.write(bytes, offset, len);
		} finally {
	        close(out);
		}
	}

	/**
	 *将字节数组保存到文件
	 */
	public static void writeFile(File file, byte[] bytes) throws Exception {
		writeFile(file, bytes, 0, bytes.length);
	}

	/**
	 * 安静地关闭，不抛出异常
	 */
	public static void close(Closeable handle) {
		if(handle == null) { return; }
		try { handle.close(); } catch(Exception e) {}
	}
}
